package no.ntnu.fp.gui;

import java.awt.BorderLayout;
import java.awt.FlowLayout;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.ListModel;
import javax.swing.border.EmptyBorder;
import javax.swing.JComboBox;
import java.awt.Label;
import javax.swing.JEditorPane;
import javax.swing.JList;
import javax.swing.JSeparator;

import no.ntnu.fp.client.Appointment;
import no.ntnu.fp.client.CalendarClient;
import no.ntnu.fp.client.MeetingRoom;
import no.ntnu.fp.client.User;
import no.ntnu.fp.server.Console;

import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.ListSelectionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

public class NewAppointmentDialog extends JDialog {

	private static final long serialVersionUID = -5605381761670907661L;
	private final JPanel contentPanel = new JPanel();
	private final CalendarClient cP;
	private JComboBox fromHourBox = new JComboBox();
	private JComboBox toHourBox = new JComboBox();
	private JComboBox fromMinBox = new JComboBox();
	private JComboBox toMinBox = new JComboBox();
	private JComboBox roomBox = new JComboBox();
	private JEditorPane descriptionPane;
	private JList employeeList = new JList();
	private JList participantList = new JList();
	private JList appointmentList = new JList();
	private int row;
	private int column;
	private Appointment[] appointments;
	private ArrayList<User> par = new ArrayList<User>();
	private final String day, month, year;
	private String owner;

	private JButton updateBtn = new JButton("Update");
	private JButton deleteAppBtn = new JButton("Delete");
	private JButton cancelBtn = new JButton("Cancel");

	public NewAppointmentDialog(final CalendarClient cP, int row, int column, final int day, final int month, final int year, ArrayList<Appointment> apps ) {
		this.cP = cP;
		this.row = row;
		this.column = column;
		this.day = Integer.toString(day);
		this.month = Integer.toString(month);
		this.year = Integer.toString(year);
		this.owner = cP.getLoggedInUser().getName();

		setTitle("New Appointment");
		setBounds(100, 100, 815, 572);
		getContentPane().setLayout(new BorderLayout());
		contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
		getContentPane().add(contentPanel, BorderLayout.CENTER);
		contentPanel.setLayout(null);

		for (int i=0; i<=9; i++) {
			fromHourBox.addItem("0"+String.valueOf(i));
			toHourBox.addItem("0"+String.valueOf(i));
		}
		// Populate fromHourBox and toHourBox
		for (int i=10; i<=24; i++){
			fromHourBox.addItem(String.valueOf(i));
			toHourBox.addItem(String.valueOf(i));
		}

		// Populate fromMinBox and toMinBox
		fromMinBox.addItem("0"+String.valueOf(0));
		toMinBox.addItem("0"+String.valueOf(0));
		for (int i=1; i<=3; i++) {
			fromMinBox.addItem(String.valueOf(i*15));
			toMinBox.addItem(String.valueOf(i*15));
		}
		toMinBox.setSelectedIndex(0);
		fromMinBox.setSelectedIndex(0);
		toHourBox.setSelectedIndex(0);
		fromHourBox.setSelectedIndex(0);

		fromHourBox.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				updateRoomList();
			}
		});
		fromHourBox.setBounds(62, 12, 56, 23);
		contentPanel.add(fromHourBox);
		
		toHourBox.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				updateRoomList();
			}
		});
		toHourBox.setBounds(62, 47, 57, 23);		
		contentPanel.add(toHourBox);
		
		fromMinBox.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				updateRoomList();
			}
		});
		fromMinBox.setBounds(130, 12, 56, 23);
		contentPanel.add(fromMinBox);
		
		toMinBox.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				updateRoomList();
			}
		});
		toMinBox.setBounds(131, 47, 56, 23);
		contentPanel.add(toMinBox);

		Label label = new Label("From :");
		label.setBounds(12, 12, 47, 21);
		contentPanel.add(label);

		Label label_1 = new Label("To : ");
		label_1.setBounds(12, 49, 47, 21);
		contentPanel.add(label_1);

		descriptionPane = new JEditorPane(){
			private static final long serialVersionUID = 1L;

			//Never return a empty string (causes SQL error)
			public String getText(){
				if( super.getText().isEmpty() ) return " ";
				return super.getText();
			}
		};
		descriptionPane.setBounds(409, 12, 369, 97);
		contentPanel.add(descriptionPane);

		Label descriptionLabel = new Label("Description");
		descriptionLabel.setBounds(317, 12, 86, 21);
		contentPanel.add(descriptionLabel);

		employeeList.setBounds(12, 127, 327, 175);
		employeeList.setListData( cP.getUsers().toArray() );
		contentPanel.add(employeeList);

		participantList.setBounds(432, 121, 346, 175);
		par.add(cP.getLoggedInUser());
		participantList.setListData( par.toArray() );
		contentPanel.add(participantList);


		JButton addParticipantBtn = new JButton(">");
		addParticipantBtn.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				addParBtnClicked(e);
			}
		});
		addParticipantBtn.setBounds(370, 154, 50, 23);
		contentPanel.add(addParticipantBtn);

		JButton removeParticipantBtn = new JButton("<");
		removeParticipantBtn.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				rmParBtnClicked(e);
			}
		});
		removeParticipantBtn.setBounds(370, 206, 50, 24);
		contentPanel.add(removeParticipantBtn);

		Label label_2 = new Label(":");
		label_2.setBounds(124, 12, 6, 21);
		contentPanel.add(label_2);

		Label label_3 = new Label(":");
		label_3.setBounds(124, 47, 6, 21);
		contentPanel.add(label_3);
		appointmentList.addListSelectionListener(new ListSelectionListener() {
			public void valueChanged(ListSelectionEvent e) {
				Appointment app = getSelectedAppointment();
				updateBtn.setEnabled(app.getOwner().equals(cP.getLoggedInUser().getUname()));
				deleteAppBtn.setEnabled(app.getOwner().equals(cP.getLoggedInUser().getUname()));
			}
		});

		appointmentList.setBounds(191, 352, 345, 146);
		contentPanel.add(appointmentList);

		Label label_4 = new Label("Room :");
		label_4.setBounds(12, 88, 47, 21);
		contentPanel.add(label_4);

		roomBox.setBounds(62, 86, 240, 23);
		contentPanel.add(roomBox);

		JButton editAppBtn = new JButton("Edit");
		editAppBtn.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				editBtnClicked(e);
			}
		});

		editAppBtn.setBounds(548, 358, 101, 24);
		contentPanel.add(editAppBtn);

		JSeparator separator = new JSeparator();
		separator.setBounds(12, 327, 1, 2);
		contentPanel.add(separator);

		JSeparator separator_1 = new JSeparator();
		separator_1.setBounds(12, 314, 783, 4);
		contentPanel.add(separator_1);

		Label editLabel = new Label("Edit existing appointment");
		editLabel.setBounds(285, 318, 168, 21);
		contentPanel.add(editLabel);

		deleteAppBtn.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				deleteAppBtnClicked(e);
			}
		});
		deleteAppBtn.setBounds(547, 427, 102, 24);
		contentPanel.add(deleteAppBtn);

		updateBtn.setBounds(548, 391, 101, 24);
		contentPanel.add(updateBtn);
		updateBtn.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				updateBtnClicked(e);
			}
		});

		JPanel buttonPane = new JPanel();
		buttonPane.setLayout(new FlowLayout(FlowLayout.RIGHT));
		getContentPane().add(buttonPane, BorderLayout.SOUTH);

		JButton addBtn = new JButton("Add");
		addBtn.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				addAppBtnClicked(e);
			}
		});

		addBtn.setActionCommand("OK");
		buttonPane.add(addBtn);
		getRootPane().setDefaultButton(addBtn);
		cancelBtn.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				cancelBtnClicked(e);
			}
		});

		cancelBtn.setActionCommand("Cancel");
		buttonPane.add(cancelBtn);

		// Populate list of appointments
		appointments = new Appointment[apps.size()];
		try {
			for (int i=0; i<apps.size(); i++) {
				Appointment a = apps.get(i);
				if (a.getDay() == day) {
					appointments[i] = a;
				}
			}
			appointmentList.setListData(appointments);
			
			JButton viewRepliesBtn = new JButton("View Replies");
			viewRepliesBtn.addMouseListener(new MouseAdapter() {
				@Override
				public void mouseClicked(MouseEvent e) {
					viewRepliesBtnClicked(e);
				}
			});
			viewRepliesBtn.setBounds(31, 403, 150, 24);
			contentPanel.add(viewRepliesBtn);

		} catch (Exception e) {
			Console.printConsole("No appointments to display");
			e.printStackTrace();
		}
		
		//do last
		updateRoomList();
	}
	
	private String getToTime(){
		return toHourBox.getSelectedItem().toString() + toMinBox.getSelectedItem().toString();
	}
	
	private String getFromTime(){
		return fromHourBox.getSelectedItem().toString() + fromMinBox.getSelectedItem().toString();
	}
	
	/*
	 * Updates the selected appointment
	 */
	protected void updateBtnClicked(MouseEvent e) {
		String description = descriptionPane.getText();
		MeetingRoom room = (MeetingRoom)roomBox.getSelectedItem();
		ArrayList<String> participants = new ArrayList<String>();
		for (User user : par) {
			participants.add(user.getUname());
		}
		String appID = Integer.toString(getSelectedAppointment().getID());
		cP.editAppointment(appID, cP.getLoggedInUser().getUname(), description, room, day, month, year, getFromTime(), getToTime(), participants, row, column);	
		cancelBtnClicked(e);
	}

	// Repopulate roomlist
	private void updateRoomList() {
		roomBox.removeAllItems();
		roomBox.addItem(null);
		for( Object room : cP.getFreeRooms(String.valueOf(day), String.valueOf(month), String.valueOf(year), getFromTime(), getToTime()) ){
			roomBox.addItem(room);
		}			
		roomBox.removeItemAt(1);
	}
	
	/*
	 * Gets the information entered and adds the appointment to the database
	 */
	public void addAppBtnClicked(MouseEvent e) {
		String from = fromHourBox.getSelectedItem().toString() + fromMinBox.getSelectedItem().toString();
		String to = toHourBox.getSelectedItem().toString() + toMinBox.getSelectedItem().toString();
		String owner = cP.getLoggedInUser().getUname();
		String description = descriptionPane.getText();
		MeetingRoom  room;
		if(roomBox.getSelectedItem() == null) {
			room = new MeetingRoom(1, "none", "0");
		} else {
			room = (MeetingRoom) roomBox.getSelectedItem();
		}

		ListModel listModel = participantList.getModel();
		ArrayList<String> participants = new ArrayList<String>();

		for( int i = 0; i < listModel.getSize(); i++ ) {

			//Was this the last user?
			if( listModel.getElementAt(i) == null ) break;

			//Add him/her!
			User addMe = (User)listModel.getElementAt(i);
			participants.add( addMe.getUname() );
		}

		cP.addAppointment(owner, description, room, day, month, year, from, to, participants, row, column);	
		descriptionPane.setText(" ");
		cancelBtnClicked(e);
	}

	/*
	 * Gets information about the selected appointment, and displays it in the editable fields
	 */
	public void editBtnClicked(MouseEvent e) {
		Appointment a = getSelectedAppointment();
		String description = a.getDescription();
		String fromTime = a.getFromTime();
		String toTime = a.getToTime();
		int fromHour, fromMin, toHour, toMin;
		// Stupid hour length fix
		if(fromTime.length() == 1){
			fromHour = 0;
			fromMin = 0;
		}
		else if(fromTime.length () == 2){
			fromHour = 2;
			fromMin = Integer.parseInt(fromTime);
		}
		else if (fromTime.length() == 3) {
			fromHour = Integer.parseInt(fromTime.substring(0,1));
			fromMin = Integer.parseInt(fromTime.substring(1));
		} else{
			fromHour = Integer.parseInt(fromTime.substring(0,2));
			fromMin = Integer.parseInt(fromTime.substring(2));
		}
		if (toTime.length() == 3) {
			toHour = Integer.parseInt(toTime.substring(0,1));
			toMin = Integer.parseInt(toTime.substring(1));
		} else {
			toHour = Integer.parseInt(toTime.substring(0,2));
			toMin = Integer.parseInt(toTime.substring(2));
		}
		fromMinBox.setSelectedIndex(fromMin/15);
		fromHourBox.setSelectedIndex(fromHour);
		toMinBox.setSelectedIndex(toMin/15);
		toHourBox.setSelectedIndex(toHour);
		descriptionPane.setText(description);
		participantList.setListData(cP.getParticipants(a.getID()).toArray());
	}

	/*
	 * Adds the selected employee to the list of the participants
	 */
	public void addParBtnClicked(MouseEvent e) {
		Object[] selected = employeeList.getSelectedValues();
		
		for( Object o : selected ){
			if( par.get(0).getUname().equals(((User)o).getUname()) ) continue;
			if( par.contains(o) ) continue;
			par.add((User)o);
		}
		
		participantList.setListData(par.toArray());
	}

	/*
	 * Closes the NewAppointmentDialog
	 */
	public void cancelBtnClicked(MouseEvent e) {
		cP.refreshCalendarGui();
		dispose();
	}

	/*
	 * NOT WORKING ATM Removes the selected employee from the list of participants
	 */
	public void rmParBtnClicked(MouseEvent e) {
		Object selected[] = participantList.getSelectedValues();
		
		for( Object o : selected ){
			if(cP.getLoggedInUser().getUname().equals(((User)o).getUname())) {
				JOptionPane.showMessageDialog(null, "You cannot remove yourself from the meeting!");
				continue;
			}
			for( User s : par ){
				if( s.getUname().equals(((User)o).getUname()) ) {
						par.remove(s);
						break;
				}
			}
		}
		
		participantList.setListData(par.toArray());
	}

	private Appointment getSelectedAppointment(){
		return (Appointment)appointmentList.getSelectedValue();
	}

	public void deleteAppBtnClicked(MouseEvent e) {	
		cP.deleteAppointment( String.valueOf(getSelectedAppointment().getID()) );
		cancelBtnClicked(e);
	}
	
	public void viewRepliesBtnClicked(MouseEvent e) {
		Replies dialog = new Replies( cP.getAppointmentReplies(getSelectedAppointment().getID()) );
		dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
		dialog.setVisible(true);
	}
}
